﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartSpace.Core
{
    public class CoreSearcher : ICoreSearcher
    {
        public PagedResult<Privilege> FindPrivilege(string type, string name, string caption, int start, int limit)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                string sql = "select * from core_privilege where type like {0} and code like {1} and caption like {2}";
                List<Privilege> list = context.Database.SqlQuery<Privilege>(sql,
                    string.Format("%{0}%", type),
                    string.Format("%{0}%", name),
                    string.Format("%{0}%", caption)).Skip(start).Take(limit).ToList();

                int total = context.Database.SqlQuery<Privilege>(sql,
                    string.Format("%{0}%", type),
                    string.Format("%{0}%", name),
                    string.Format("%{0}%", caption)).Count();

                return new PagedResult<Privilege>(start, limit, total, list);
            }
        }

        public ListResult<Privilege> FindPrivilegeNotInRole(Guid roleId)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                string sql = @"select cp.* from core_privilege as cp
where cp.Id not in (select crp.privilegeid from core_roleprivilege as crp
 join core_role as cr on cr.Id = crp.RoleId where cr.Id={0})";

                List<Privilege> list = context.Database.SqlQuery<Privilege>(sql, roleId).ToList();
                return new ListResult<Privilege>(list);
            }
        }

        public ListResult<RolePrivilegeDetail> FindPrivilege(Guid roleId)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                string sql = @"select cr.Id as roleId, cr.Code as rolecode,cr.Caption as rolecaption, cp.Id as privilegeid, cp.Code as privilegecode, cp.Caption as privilegecaption, 'OWN' as privilegeType
 from core_privilege as cp
 join core_roleprivilege as crp on crp.PrivilegeId = cp.Id
	join core_role as cr on cr.Id = crp.RoleId
	where crp.RoleId ={0}";
                List<RolePrivilegeDetail> list = context.Database.SqlQuery<RolePrivilegeDetail>(sql, roleId).ToList();

                List<Guid> parentIds = context.Set<RoleRelation>().Where(p => p.RoleId == roleId).Select(p => p.ParentId).ToList();
                for (int index = 0; index < parentIds.Count; index++)
                {
                    list.AddRange(FindParentPrivilege(context, parentIds[index]));
                }

                return new ListResult<RolePrivilegeDetail>(list);
            }
        }

        private List<RolePrivilegeDetail> FindParentPrivilege(CoreDbContext context, Guid roleId)
        {
            string sql = @"select cr.Id as roleId, cr.Code as rolecode,cr.Caption as rolecaption, cp.Id as privilegeid, cp.Code as privilegecode, cp.Caption as privilegecaption, 'INHERITED' as privilegeType
 from core_privilege as cp
 join core_roleprivilege as crp on crp.PrivilegeId = cp.Id
	join core_role as cr on cr.Id = crp.RoleId
	where crp.RoleId ={0}";
            List<RolePrivilegeDetail> list = context.Database.SqlQuery<RolePrivilegeDetail>(sql, roleId).ToList();

            List<Guid> parentIds = context.Set<RoleRelation>().Where(p => p.RoleId == roleId).Select(p => p.ParentId).ToList();
            for (int index = 0; index < parentIds.Count; index++)
            {
                list.AddRange(FindParentPrivilege(context, parentIds[index]));
            }

            return list;
        }

        public ListResult<Role> FindRoles(string filter)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                string sql = "select * from core_role where code like {0} and caption like {0}";
                List<Role> list = context.Database.SqlQuery<Role>(sql,
                    string.Format("%{0}%", filter)).ToList();
                return new ListResult<Role>(list);
            }
        }
    }
}
